package com.thinkingstar.iads.common.service;

import org.nutz.dao.Chain;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.lang.util.NutMap;

import com.thinkingstar.iads.common.page.Pagination;

import java.util.List;

public interface EntityRepositoryServiceI<T> {

    Dao dao();

    /**
     * 统计符合条件的对象表条数
     * @param cnd
     * @return
     */
    int count(Condition cnd);
    
    /**
     * 统计对象表条数
     * @return
     */
    int count();
    
    /**
     * 统计符合条件的记录条数
     * @param tableName
     * @param cnd
     * @return
     */
    int count(String tableName, Condition cnd);

    /**
     * 统计表记录条数
     * @param tableName
     * @return
     */
    int count(String tableName);

    /**
     * 通过数字型主键查询对象
     * @param id
     * @return
     */
    T fetch(long id);

    /**
     * 通过字符型主键查询对象
     * @param id
     * @return
     */
    T fetch(String id);

    /**
     * 查询关联表
     * @param obj   数据对象,可以是普通对象或集合,但不是类
     * @param regex 为null查询全部,支持通配符 ^(a|b)$
     * @return
     */
    T fetchLinks(T obj, String regex);

    /**
     * 查询关联表
     * @param obj   数据对象,可以是普通对象或集合,但不是类
     * @param regex 为null查询全部,支持通配符 ^(a|b)$
     * @param cnd   关联字段的过滤(排序,条件语句,分页等)
     * @return
     */
    T fetchLinks(T obj, String regex, Condition cnd);

    /**
     * 查出符合条件的第一条记录
     * @param cnd 查询条件
     * @return 实体, 如不存在则为null
     */
    T fetch(Condition cnd);

    /**
     * 复合主键专用
     * @param pks 键值
     * @return 对象 T
     */
    T fetchx(Object... pks);

    /**
     * 复合主键专用
     * @param pks 键值
     * @return 对象 T
     */
    boolean exists(Object... pks);

    /**
     * 将一个对象插入到一个数据库
     * @param obj 要被插入的对象
     *            它可以是：
     *            普通 POJO
     *            集合
     *            数组
     *            Map
     *            注意：如果是集合，数组或者 Map，所有的对象必须类型相同，否则可能会出错
     * @return 插入后的对象
     */
    T insert(T obj);

    /**
     * 自由的向一个数据表插入一条数据
     *
     * @param tableName 表名
     * @param chain     数据名值链
     */
    void insert(String tableName, Chain chain);

    /**
     * 快速插入一个对象,对象的 '@Prev' 以及 '@Next' 在这个函数里不起作用
     * @param obj
     * @return
     */
    T fastInsert(T obj);

    /**
     * 更新数据
     * @param obj
     * @return
     */
    int update(Object obj);
    
    /**
     * 更新数据忽略值为null的字段
     * @param obj
     * @return
     */
    int updateIgnoreNull(Object obj);
    
    /**
     * 部分更新实体表
     * @param chain
     * @param cnd
     * @return
     */
    int update(Chain chain, Condition cnd);

    /**
     * 部分更新表
     * @param tableName
     * @param chain
     * @param cnd
     * @return
     */
    int update(String tableName, Chain chain, Condition cnd);

    
    int getMaxId();

    int delete(long id);

    int delete(int id);

    int delete(String id);

    void delete(Integer[] ids);

    void delete(Long[] ids);

    void delete(String[] ids);

    int clear();

    int clear(String tableName);

    int clear(Condition cnd);

    int clear(String tableName, Condition cnd);

    int vDelete(String id);

    int vDelete(String[] ids);

    T getField(String fieldName, long id);

    T getField(String fieldName, int id);

    T getField(String fieldName, String name);

    T getField(String fieldName, Condition cnd);

    List<T> query(String fieldName, Condition cnd);

    List<T> query(Condition cnd);

    int count(Sql sql);

    List<Record> list(Sql sql);

    NutMap getMap(Sql sql);
    
    Pagination listPage(Integer pageNumber, Condition cnd);

    Pagination listPage(Integer pageNumber, Sql sql);

    Pagination listPage(Integer pageNumber, String tableName, Condition cnd);

    Pagination listPage(Integer pageNumber, int pageSize, Condition cnd);

    Pagination listPage(Integer pageNumber, int pageSize, Condition cnd, String fieldName);

    Pagination listPage(Integer pageNumber, int pageSize, String tableName, Condition cnd);

    Pagination listPage(Integer pageNumber, int pageSize, Sql sql);

}
